package Servers

import (
	"PBMessage"
	"SGNet"

	. "Servers/BaseServer"
	log "misc/seelog"
)

type GateServer struct {
	BaseServer
	HallServer   IServer
	SceneServers map[string]IServer
}

func NewGateServer(hallServer IServer) *GateServer {
	retServer := &GateServer{}
	retServer.BaseServer.New()
	SGNet.MessageDispatcher = retServer.ClientSessionMessage
	SGNet.ClientLostMessage = retServer.ClientLostMessage
	retServer.HallServer = hallServer
	retServer.SceneServers = make(map[string]IServer)
	retServer.Init()
	return retServer
}

func (gateServer *GateServer) GetServerType() int {
	return Server_Gate
}
func (gateServer *GateServer) Init() {
	gateServer.AddCommandHandler(CommonID_NewGameScene, gateServer.NewGameSceneHandler)
	gateServer.AddCommandHandler(CommonID_DestoryGameScene, gateServer.DestorySceneHandler)
	gateServer.AddCommandHandler(CommonID_PlayerBackToHall, func(message *SGNet.Message) {
		gateServer.HallServer.PushMessage(message)
	})
}

func (gateServer *GateServer) ClientSessionMessage(sess *SGNet.Session, msgId uint16, msgData []byte) {
	ServerID := PBMessage.GetServerID(msgId)
	switch ServerID {
	case Server_Hall:
		gateServer.HallServer.PushMessage(&SGNet.Message{Type: MessageType_Client, Sess: sess, Id: msgId, Data: msgData, Param: nil})
	case Server_Scene:
		sceneServer := sess.UserData.(IPlayer).GetServer()
		sceneServer.PushMessage(&SGNet.Message{Type: MessageType_Client, Sess: sess, Id: msgId, Data: msgData, Param: nil})
	}
}

func (gateServer *GateServer) ClientLostMessage(sess *SGNet.Session) {
	defer func() {
		if err := recover(); err != nil {
			log.Error(err)
		}
	}()
	log.Info("Gate收到了玩家掉线的消息 Account: ", sess.UserData.(IPlayer).GetAccountModel().NickName)
	if sess.UserData == nil {
		log.Info("ClientLostMessage sess.UserData is nil")
		return
	}
	clientLostMessageData := &SGNet.Message{Type: MessageType_Command, Sess: sess, Id: CommonID_ClientLost, Data: nil, Param: nil}
	player := sess.UserData.(IPlayer)
	server := player.GetServer()
	server.PushMessage(clientLostMessageData)
}

func (gateServer *GateServer) NewGameSceneHandler(message *SGNet.Message) {
	struuid := message.Param["uuid"].(string)
	hallPlayers := message.Param["hallPlayers"].([]*HallPlayer)
	readyPlayers := message.Param["readyPlayers"].([]*PBMessage.ReadRoomPlayer)
	mapid := message.Param["mapid"].(int32)
	sceneServer := NewSceneServer(struuid, hallPlayers, readyPlayers, mapid)
	gateServer.SceneServers[struuid] = sceneServer
	sceneServer.GateServer = gateServer
}

func (gateServer *GateServer) DestorySceneHandler(message *SGNet.Message) {
	sceneId := message.Param["sceneId"].(string)
	delete(gateServer.SceneServers, sceneId)
}
